package org.lemon.cla.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.lemon.cla.pojo.News;
import org.lemon.cla.vo.NewsVo;
import org.lemon.cla.enums.NewsCategoryEnum;
import org.lemon.cla.dto.request.NewsSearchRequest;

@Mapper
public interface NewsMapper extends BaseMapper<News> {

    // 联查的公共字段片段
    String JOIN_USER_SELECT_FIELDS =
            "u.username AS publisherUsername, " +
                    "u.avatar_url AS publisherAvatarUrl, " +
                    "u.real_name AS publisherRealName, " +
                    "u.phone AS publisherPhone, " +
                    "u.email AS publisherEmail, " +
                    "u.role AS publisherRole, " +
                    "u.is_deleted AS publisherIsDeleted "; // <-- 添加 is_deleted 字段

    /**
     * 根据新闻ID获取新闻详情，包含发布者信息。
     * @param newsId 新闻ID
     * @return 新闻视图对象
     */
    @Select("SELECT n.*, " +
            JOIN_USER_SELECT_FIELDS + // 复用公共字段
            "FROM news n " +
            "LEFT JOIN user u ON n.publisher_id = u.user_id " +
            "WHERE n.news_id = #{newsId}")
    NewsVo selectNewsVoById(@Param("newsId") Long newsId);

    /**
     * 分页查询所有新闻，包含发布者信息。
     * @param page 分页对象
     * @return 分页新闻视图对象列表
     */
    @Select("SELECT n.*, " +
            JOIN_USER_SELECT_FIELDS + // 复用公共字段
            "FROM news n " +
            "LEFT JOIN user u ON n.publisher_id = u.user_id " +
            "ORDER BY n.publish_time DESC")
    IPage<NewsVo> selectNewsVoPage(IPage<NewsVo> page);

    /**
     * 根据多个条件模糊查询新闻，包括发布人姓名（联查user表），返回 NewsVo 列表。
     *
     * @param page 分页对象
     * @param req 查询请求DTO (命名为req以便在script中引用)
     * @return 分页新闻视图对象列表
     */
    @Select("<script>" +
            "SELECT n.*, " +
            JOIN_USER_SELECT_FIELDS + // 复用公共字段
            "FROM news n " +
            "LEFT JOIN user u ON n.publisher_id = u.user_id " +
            "<where>" +
            "  <if test='req.title != null and req.title != \"\"'>" +
            "    AND n.title LIKE CONCAT('%', #{req.title}, '%')" +
            "  </if>" +
            "  <if test='req.publisherName != null and req.publisherName != \"\"'>" +
            "    AND u.username LIKE CONCAT('%', #{req.publisherName}, '%')" + // publisherName 针对 u.username 模糊查询
            "  </if>" +
            "  <if test='req.publishTimeStart != null'>" +
            "    AND n.publish_time &gt;= #{req.publishTimeStart}" +
            "  </if>" +
            "  <if test='req.publishTimeEnd != null'>" +
            "    AND n.publish_time &lt;= #{req.publishTimeEnd}" +
            "  </if>" +
            "  <if test='req.category != null'>" +
            "    AND n.category = #{req.category}" +
            "  </if>" +
            "</where>" +
            "ORDER BY n.publish_time DESC" +
            "</script>")
    IPage<NewsVo> selectNewsVoByMultiConditions(
            IPage<NewsVo> page,
            @Param("req") NewsSearchRequest request
    );

    /**
     * 根据类别查询新闻，返回 NewsVo 列表 (无需模糊查询)
     * 专门为 getNewsByCategory 准备，因为它是 GET 请求，使用 QueryWrapper
     * 这个方法需要特殊处理，因为 QueryWrapper 不支持联表自定义选择字段。
     * 最佳实践是，getNewsByCategory 也通过 POST /search 实现，或者在 Service 层手动转换。
     * 为了不改动getNewsByCategory的GET请求方式，我们暂时将其转换为一个特殊情况。
     * 更好的方法是使用 `QueryWrapper` 后，再通过 Java 代码手动填充 publisher 信息，或强制前端也使用 Post/Search.
     * 考虑到你之前的 NewsController.getNewsByCategory 是直接通过Service.list(queryWrapper)获取News的，
     * 而现在NewsMapper只返回NewsVo。所以需要一个返回NewsVo的方法。
     * 考虑到性能，如果只有category，直接使用Page的查询可能更好。
     *
     * 如果要保持 `getNewsByCategory` 的 `QueryWrapper` 方式，但又要包含 publisher 信息，
     * 这会要求 Mybatis-Plus 能够自定义联表查询，或者 Service 层二次查询填充。
     * 目前Mapper的BaseMapper无法直接提供带JOIN的QueryWrapper。
     * 所以，这里我们通过 `searchNewsByConditions` 来统一处理。
     */
}